/*
  内置方法/函数：
    print();
  
  自定义方法：
    自定义方法的基本格式： 没有返回值用void代替

    返回类型  方法名称（参数1，参数2,...）{
      方法体
      return 返回值;
    }


  闭包:
  1、全局变量特点:    全局变量常驻内存、全局变量污染全局
  2、局部变量的特点：  不常驻内存会被垃圾机制回收、不会污染全局  

   想实现的功能：
    1.常驻内存        
    2.不污染全局   
      产生了闭包,闭包可以解决这个问题.....  
      闭包: 函数嵌套函数, 内部函数会调用外部函数的变量或参数, 变量或参数不会被系统回收(不会释放内存)
      闭包的写法： 函数嵌套函数，并return 里面的函数，这样就形成了闭包。
*/

// 都是自定义方法
int getNum() {
  var myNum = 123;
  return myNum;
}

String printUserInfo() {
  return 'this is str';
}

// 声明全局变量  测试闭包
var a = 100;

main() {
  // 1. 基础的函数
  // int 是形参 n的类型
  // int sumNum(int n) {
  //   var sum = 0;
  //   for (var i = 1; i <= n; i++) {
  //     sum += i;
  //   }
  //   return sum;
  // }

  // print(sumNum(5));

  // 2. 形参 给上默认值
  // String printUserInfo(String username, [int age = 0]) {
  //   //行参
  //   if (age != 0) {
  //     return "姓名:$username---年龄:$age";
  //   }
  //   return "姓名:$username---年龄保密";
  // }

  // print(printUserInfo('张三', 21)); //实参 实参传入时不能打乱顺序
  // print(printUserInfo('张三'));

  // 3. 命名参数
  // String printUserInfo(String username, {int age = 0, String sex = '男'}) {
  //   //行参
  //   if (age != 0) {
  //     return "姓名:$username---性别:$sex--年龄:$age";
  //   }
  //   return "姓名:$username---性别:$sex--年龄保密";
  // }

  // print(printUserInfo('卡莎', sex: '女', age: 20)); // 传入实参时 可以打乱顺序

  // 4. 箭头函数
  // 缺点:  箭头函数内只能写一条语句

  /*需求：使用forEach打印下面List里面的数据*/

  // List list=['苹果','香蕉','西瓜'];
  // list.forEach((value){
  //   print(value);
  // });
  // list.forEach((value)=>print(value));

  //注意和方法的区别: 箭头函数内只能写一条语句，并且语句后面没有分号(;)
  // list.forEach((value)=>{
  //   print(value)
  // });

  /*需求：修改下面List里面的数据，让数组中大于2的值乘以2*/
  // List list = [4, 1, 2, 3, 4];
  // var newList = list.map((value) {
  //   if (value > 2) {
  //     return value * 2;
  //   }
  //   return value;
  // });
  // print(newList.toList());
  // var newList = list.map((value) => value > 2 ? value * 2 : value).toList();
  // print(newList);

  //  5. 函数的互相调用
  /*
  需求：    
  1、定义一个方法isEvenNumber来判断一个数是否是偶数  
  2、定义一个方法打印1-n以内的所有偶数
  */

  // 5.1 定义一个方法isEvenNumber来判断一个数是否是偶数
  // bool isEvenNumber(int n) => (n % 2 == 0 ? true : false);

  // 5.2 定义一个方法打印1-n以内的所有偶数
  // printNum(int n) {
  //   for (var i = 1; i <= n; i++) {
  //     if (isEvenNumber(i)) {
  //       print(i);
  //     }
  //   }
  // }

  // printNum(10);

  // 6. 闭包
  // 先区别全局变量和局部变量
  // print(a); // 打印全局变量
  // fn() {
  //   a++;
  //   var myNum = 1;
  //   myNum++;
  //   print(myNum); // 函数内部声明的变量是局部变量
  //   print(a);
  // }

  // fn();
  // fn();
  // fn();

  fn() {
    var a = 123; /*不会污染全局   常驻内存*/
    return () {
      a++;
      print(a);
    };
  }

  var b = fn();
  b();
  b();
  b();
}
